﻿// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com

// ReSharper disable CheckNamespace
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable CommentTypo
// ReSharper disable IdentifierTypo
// ReSharper disable InconsistentNaming
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable StringLiteralTypo
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedParameter.Local
// ReSharper disable UnusedType.Global

/* Barman.cs -- менеджер печати читательских билетов
 * Ars Magna project, http://arsmagna.ru
 */

#region Using directives

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.IO;

#endregion

#nullable enable

namespace AM.Drawing.CardPrinting;

/// <summary>
/// Менеджер печати читательских билетов.
/// </summary>
public sealed class Barman
{
    #region Events

    /// <summary>
    /// Данные изменены.
    /// </summary>
    public event EventHandler? DataChanged;

    #endregion

    #region Properties

    // /// <summary>
    // /// Gets or sets the printer.
    // /// </summary>
    // /// <value>
    // /// The printer.
    // /// </value>
    // public PrinterInfo Printer
    // {
    //     get { return _printer; }
    //     set
    //     {
    //         _printer = value;
    //         OnDataChanged();
    //     }
    // }
    //
    // /// <summary>
    // /// Gets or sets the human.
    // /// </summary>
    // /// <value>
    // /// The human.
    // /// </value>
    // public HumanInfo Human
    // {
    //     get { return _human; }
    //     set
    //     {
    //         _human = value;
    //         OnDataChanged();
    //     }
    // }

    /// <summary>
    /// Gets or sets the card.
    /// </summary>
    /// <value>
    /// The card.
    /// </value>
    public CardInfo? Card
    {
        get => _card;
        set
        {
            _card = value;
            OnDataChanged();
        }
    }

    #endregion

    #region Private members

    //private PrinterInfo _printer;

    //private HumanInfo _human;

    private CardInfo? _card;

    private void OnDataChanged() => DataChanged?.Invoke (this, EventArgs.Empty);

    private Image? _image;

    void document_PrintPage
        (
            object sender,
            PrintPageEventArgs e
        )
    {
        var graphics = e.Graphics.ThrowIfNull();

        if (_image is not null)
        {
            graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
            graphics.SmoothingMode = SmoothingMode.None;
            graphics.PixelOffsetMode = PixelOffsetMode.None;
            graphics.DrawImage (_image, 0, 0, e.PageBounds.Width, e.PageBounds.Height);
            e.HasMorePages = false;
        }
    }

    #endregion

    #region Public methods

    /// <summary>
    /// Загрузка указанного файла.
    /// </summary>
    public void Load
        (
            string fileName
        )
    {
        Sure.FileExists (fileName);

        var extension = Path.GetExtension (fileName);
        if (!string.IsNullOrEmpty (extension))
        {
            extension = extension.ToLowerInvariant();
        }

        switch (extension)
        {
            case ".card":
                Card = CardInfo.LoadXml (fileName);
                break;

            case ".printer":
                // Printer = PrinterInfo.LoadXml(fileName);
                break;

            case ".reader":
                //Human = HumanInfo.LoadXml(fileName);
                break;

            case ".irbis":
                // Human = HumanInfo.LoadIrbis(fileName);
                break;

            case ".iso":
                // Human = HumanInfo.LoadIso(fileName);
                break;

            default:
                throw new ApplicationException ("Файл неизвестного формата");
        }
    }

    /// <summary>
    /// Верификация всей информации, хранящейся в экземпляре.
    /// </summary>
    public void Verify()
    {
        // if (Printer == null)
        // {
        //     throw new ApplicationException("Не задан принтер");
        // }
        //
        // if (Human == null)
        // {
        //     throw new ApplicationException("Не задан читатель");
        // }

        if (Card == null)
        {
            throw new ApplicationException ("Не задана карточка");
        }

        //Printer.Verify();
        //Human.Verify();
        Card.Verify();
    }

    /// <summary>
    /// Отрисовка читательского билета на карточке.
    /// </summary>
    public Image DrawCard()
    {
        // if (Card == null)
        // {
        //     MessageBox.Show("Не задана карта!");
        //     return null;
        // }
        //
        // if (Human == null)
        // {
        //     MessageBox.Show("Не задан читатель!");
        //     return null;
        // }

        //DrawingContext context = new DrawingContext
        //                            {
        //                                Printer = Printer,
        //                                Card = Card,
        //                                Human = Human
        //                            };

        //Image result = Card.Draw(context);

        //return result;

        // var source = new BindingSource
        // {
        //     DataSource = Human
        // };
        // var report = new CardReport2
        // {
        //     DataSource = source
        // };
        //
        // var options
        //     = new ImageExportOptions(ImageFormat.Bmp)
        //     {
        //         ExportMode = ImageExportMode.SingleFilePageByPage,
        //         Resolution = 300
        //     };

        // var stream = new MemoryStream();
        //
        // report.ExportToImage(stream, options);
        // stream.Seek(0, SeekOrigin.Begin);
        //
        // var result = Image.FromStream(stream);

        // result.Save ("result.bmp");

        // return result;

        throw new NotImplementedException();
    }

    /// <summary>
    /// Вывод данных на принтер.
    /// </summary>
    public void PrintCard
        (
            Image image
        )
    {
        Sure.NotNull (image);

        Verify();

        _image = image;
        var document = new PrintDocument
        {
            DocumentName = "Карточка читателя"
        };
        document.PrintPage += document_PrintPage;

        /*
        document.PrinterSettings.PrinterName = Printer.Name;
        document.DefaultPageSettings.PaperSize = new PaperSize
        (
            "Reader card",
            Printer.PageWidth,
            Printer.PageHeight
        );
        document.DefaultPageSettings.Landscape = Printer.Landscape;
        */

        document.Print();
    }

    /// <summary>
    /// Разбор аргументов командной строки.
    /// </summary>
    public void ParseCommandLine
        (
            string[] arguments
        )
    {
        Sure.NotNull (arguments);

        foreach (var fileName in arguments)
        {
            Load (fileName);
        }
    }

    // /// <summary>
    // /// Sets the reader info.
    // /// </summary>
    // /// <param name="reader">The reader.</param>
    // public void SetReaderInfo(ReaderInfo reader)
    // {
    //     if ((reader == null)
    //         || string.IsNullOrEmpty(reader.Ticket))
    //     {
    //         return;
    //     }
    //
    //     var human = new HumanInfo
    //     {
    //         Address = reader.Address,
    //         Barcode = reader.Barcode,
    //         Birthdate = reader.Birthdate,
    //         Cathedra = reader.Cathedra,
    //         Cathegory = reader.Category,
    //         Department = reader.Department,
    //         Email = reader.Mail,
    //         Group = reader.Group,
    //         JobTitle = reader.JobTitle,
    //         Name = reader.Name,
    //         Phone = reader.Phone,
    //         Registration = reader.Registered,
    //         Reregistration = reader.Reregistered
    //             .ToString(CultureInfo.InvariantCulture),
    //         Ticket = reader.Ticket
    //     };
    //     using (IReaderManager manager = new ReaderManager())
    //     {
    //         var photo = manager.GetPhoto(reader.Ticket);
    //         human.ActualImage = photo;
    //     }
    //
    //     Human = human;
    // }

    #endregion
}
